package com.ibeeking.found.cop.b.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.found.common.constants.GlobalConstant;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.cop.b.rest.service.IMsgKnowledgeGroupService;
import com.ibeeking.found.cop.b.rest.service.IMsgKnowledgeService;
import com.ibeeking.found.cop.service.common.dos.MsgKnowledgeGroupDO;
import com.ibeeking.found.cop.service.common.param.MsgKnowledgeGroupParam;
import com.ibeeking.found.cop.service.common.query.MsgKnowledgeGroupQuery;
import com.ibeeking.found.cop.service.common.vo.MsgKnowledgeGroupVO;
import com.ibeeking.found.cop.service.mapper.MsgKnowledgeGroupMapper;
import com.ibeeking.found.id.GenerateId;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.TreeFastUtils;
import com.ibeeking.nematos.utils.json.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @ClassName MsgKnowledgeGroupServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-01-27 18:50
 **/
@Service
public class MsgKnowledgeGroupServiceImpl extends ServiceImpl<MsgKnowledgeGroupMapper, MsgKnowledgeGroupDO> implements IMsgKnowledgeGroupService {

    @Resource
    private MsgKnowledgeGroupMapper msgKnowledgeGroupMapper;

    @Resource
    private IMsgKnowledgeService msgKnowledgeServiceImpl;

    @Override
    public List<MsgKnowledgeGroupVO> list(MsgKnowledgeGroupQuery query){
        List<MsgKnowledgeGroupVO> MsgKnowledgeGroupVOS = new ArrayList<>();
        LambdaQueryWrapper<MsgKnowledgeGroupDO> queryWrapper = new LambdaQueryWrapper<>(MsgKnowledgeGroupDO.class)
                .eq(query.getId()!= null, MsgKnowledgeGroupDO::getId, query.getId())
                .eq(query.getParentId() != null, MsgKnowledgeGroupDO::getParentId, query.getParentId())
                .eq(StringUtils.isNotEmpty(query.getName()), MsgKnowledgeGroupDO::getName, query.getName())
                .eq(query.getRoot()!= null, MsgKnowledgeGroupDO::getRoot, query.getRoot())
                .eq(query.getFixed()!= null, MsgKnowledgeGroupDO::getFixed, query.getFixed())
                .orderByAsc(MsgKnowledgeGroupDO::getCreateTime);
        List<MsgKnowledgeGroupDO> MsgKnowledgeGroupDOS = msgKnowledgeGroupMapper.selectList(queryWrapper);
        if(Collections3.isNotEmpty(MsgKnowledgeGroupDOS)) {
            MsgKnowledgeGroupVOS = MsgKnowledgeGroupDOS.stream().map(d->{
                MsgKnowledgeGroupVO MsgKnowledgeGroupVO = BeanUtil.convertBean(d, MsgKnowledgeGroupVO.class);
                Integer qrcodeCount = msgKnowledgeServiceImpl.summaryCount(d.getId());
                MsgKnowledgeGroupVO.setQrcodeNum(qrcodeCount);
                return MsgKnowledgeGroupVO;
            }).collect(Collectors.toList());
        }

        return MsgKnowledgeGroupVOS;
    }

    @Override
    public List<Long> getKnowledgeIdWithSubByParentId(Long parentId){
        if (null == parentId) return Collections3.emptyList();

        LambdaQueryWrapper<MsgKnowledgeGroupDO> queryWrapper = new LambdaQueryWrapper<>(MsgKnowledgeGroupDO.class);
        queryWrapper.eq(MsgKnowledgeGroupDO::getParentId, parentId);

        List<MsgKnowledgeGroupDO> MsgKnowledgeGroupDOS = msgKnowledgeGroupMapper.selectList(queryWrapper);
        if (Collections3.isEmpty(MsgKnowledgeGroupDOS)) {
            return Collections3.emptyList();
        }
        List<Long> ids = MsgKnowledgeGroupDOS.stream().map(MsgKnowledgeGroupDO::getId).collect(Collectors.toList());

        //查询所有
        if(Collections3.isNotEmpty(ids) && ids.size() >0 ) {
            for(Long id:ids){
                if (id != null) {
                    List<Long> subIds = getBean().getKnowledgeIdWithSubByParentId(id);
                    ids.addAll(subIds);
                }
            };
        }
        ids.add(parentId);
        return ids;
    }

    @Override
    public List<MsgKnowledgeGroupVO> listByParentId(Long parentId){
        if (null == parentId) {
            parentId = GlobalConstant.PARENT_ID;
        }
        LambdaQueryWrapper<MsgKnowledgeGroupDO> queryWrapper = new LambdaQueryWrapper<>(MsgKnowledgeGroupDO.class);
        queryWrapper.eq(MsgKnowledgeGroupDO::getParentId, parentId);

        List<MsgKnowledgeGroupDO> MsgKnowledgeGroupDOS = msgKnowledgeGroupMapper.selectList(queryWrapper);
        if (Collections3.isEmpty(MsgKnowledgeGroupDOS)) {
            return Collections3.emptyList();
        }
        List<Long> ids = MsgKnowledgeGroupDOS.stream().map(MsgKnowledgeGroupDO::getId).collect(Collectors.toList());
        ids.add(parentId);
        //查询所有
        List<MsgKnowledgeGroupDO> allMsgKnowledgeGroupDOS = msgKnowledgeGroupMapper.selectList(new LambdaQueryWrapper<>(MsgKnowledgeGroupDO.class)
                .orderByAsc(MsgKnowledgeGroupDO::getCreateTime)
                .orderByDesc(MsgKnowledgeGroupDO::getSort)
        );
        List<MsgKnowledgeGroupVO> allMsgKnowledgeGroupTrees = JsonUtils.jsonToList(allMsgKnowledgeGroupDOS, MsgKnowledgeGroupVO.class);
        if(Collections3.isNotEmpty(allMsgKnowledgeGroupTrees)) {
            allMsgKnowledgeGroupTrees.stream().forEach(d->{
                Integer qrcodeCount = msgKnowledgeServiceImpl.summaryCount(d.getId());
                d.setQrcodeNum(qrcodeCount);
            });
        }
        List<Long> result = new ArrayList<>();
        TreeFastUtils.selectLongCidByPid(result, allMsgKnowledgeGroupTrees, ids);
        result.addAll(ids);
        allMsgKnowledgeGroupTrees = allMsgKnowledgeGroupTrees.stream().filter(g -> result.contains(g.getId())).collect(Collectors.toList());
        List<MsgKnowledgeGroupVO>  MsgKnowledgeGroupVOS = TreeFastUtils.listToTree(allMsgKnowledgeGroupTrees, parentId);

        return  MsgKnowledgeGroupVOS;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(MsgKnowledgeGroupParam param) {
        checkUnique(param);
        MsgKnowledgeGroupDO entityDO = BeanUtil.convertBean(param, MsgKnowledgeGroupDO.class);
        Long id = GenerateId.generateId();
        entityDO.setId(id);
        entityDO.setFixed(0);
        entityDO.setRoot(0);
        entityDO.setSort(id);
        entityDO.setCreateBy(UserUtils.getUserId());
        entityDO.setCreateTime(LocalDateTime.now());
        entityDO.setModifyTime(LocalDateTime.now());
        return msgKnowledgeGroupMapper.insert(entityDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean modify(MsgKnowledgeGroupParam param) {
        MsgKnowledgeGroupDO entityDO = BeanUtil.convertBean(param, MsgKnowledgeGroupDO.class);
        entityDO.setModifyBy(UserUtils.getUserId());
        entityDO.setModifyTime(LocalDateTime.now());
        entityDO.setFixed(0);
        entityDO.setRoot(0);
        return msgKnowledgeGroupMapper.updateById(entityDO) > 0;
    }

    @Override
    public MsgKnowledgeGroupVO view(Long id) {
        MsgKnowledgeGroupDO entityDO = msgKnowledgeGroupMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        MsgKnowledgeGroupVO entityVO = BeanUtil.convertBean(entityDO, MsgKnowledgeGroupVO.class);
        return entityVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean del(Long id) {
        MsgKnowledgeGroupDO entityDO = msgKnowledgeGroupMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        return msgKnowledgeGroupMapper.deleteById(id) > 0;
    }
    /**
     * 校验唯一性
     *
     * @param param
     */
    public void checkUnique(MsgKnowledgeGroupParam param) {
        if (param == null) {
            throw new BusinessException("当前记录不存在!");
        }
        //code name确保等级唯一性
        LambdaQueryWrapper<MsgKnowledgeGroupDO> queryWrapper = new LambdaQueryWrapper<MsgKnowledgeGroupDO>()
                .ne(param.getId() != null, MsgKnowledgeGroupDO::getId, param.getId())
                .eq(MsgKnowledgeGroupDO::getName, param.getName());
        List<MsgKnowledgeGroupDO> dos = msgKnowledgeGroupMapper.selectList(queryWrapper);
        if (Collections3.isNotEmpty(dos)) {
            throw new BusinessException("已经存在同名的记录!");
        }
    }

    private IMsgKnowledgeGroupService getBean(){
        return SpringBeanUtil.getBean(MsgKnowledgeGroupServiceImpl.class);
    }
}
